/*
 * Copyright (c) 2024. hallele, Inc All rights reserved.
 */

package cn.hallele.infrastructure.util;

import org.apache.commons.lang3.time.DateFormatUtils;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;

/**
 * 时间处理工具
 *
 * @author anle5
 * @since 2024/7/25 23:40
 */
public class DateUtil extends DateFormatUtils {
    /**
     * 不允许new
     */
    @Deprecated
    public DateUtil() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    /**
     * 与当前时间做比较
     *
     * @param target 要判断的时间
     * @return true: target早于当前时间  false: target晚于当前时间
     */
    public static boolean isExpired(Date target) {
        return new Date().after(target);
    }

    /**
     * 与当前时间做比较
     *
     * @param target 要判断的时间
     * @return true: target早于当前时间  false: target晚于当前时间
     */
    public static boolean isExpired(LocalDateTime target) {
        return LocalDateTime.now().isAfter(target);
    }

    /**
     * 与 eqTime 时间做比较
     *
     * @param target 要判断的时间
     * @param eqTime 对比的对象
     * @return true: target早于eqTime  false: target晚于eqTime
     */
    public static boolean isExpired(LocalDateTime target, LocalDateTime eqTime) {
        return eqTime.isAfter(target);
    }

    /**
     * 与 eqTime 时间做比较
     *
     * @param target 要判断的时间
     * @param eqTime 对比的对象
     * @return true: target早于eqTime  false: target晚于eqTime
     */
    public static boolean isExpired(Date target, Date eqTime) {
        return eqTime.after(target);
    }

    /**
     * 比较时间是否在 begin 和 end 之间
     *
     * @param begin   起始时间
     * @param youWant 要比较的时间
     * @param end     结束时间
     * @return true:在 begin 和 end 之间  , false 反之,传入null参数也会返回false
     */
    public static boolean isBetween(LocalDateTime begin, LocalDateTime youWant, LocalDateTime end) {
        if (begin == null || youWant == null || end == null) {
            return false;
        }

        if (begin.equals(youWant) || end.equals(youWant)) {
            return true;
        }
        return begin.isBefore(youWant) && youWant.isBefore(end);
    }

    /**
     * 比较时间是否在 begin 和 end 之间
     *
     * @param begin   起始时间
     * @param youWant 要比较的时间
     * @param end     结束时间
     * @return true:在 begin 和 end 之间  , false 反之,传入null参数也会返回false
     */
    public static boolean isBetween(Date begin, Date youWant, Date end) {
        if (begin == null || youWant == null || end == null) {
            return false;
        }

        if (begin.equals(youWant) || end.equals(youWant)) {
            return true;
        }
        return begin.before(youWant) && youWant.before(end);
    }

    /**
     * 获取当前时间
     *
     * @return 当前时间
     */
    public static LocalDateTime now() {
        return LocalDateTime.now();
    }

    /**
     * 获取当前时间
     *
     * @return 当前时间
     */
    public static Date nowDate() {
        return new Date();
    }

    /**
     * date 转 LocalDateTime，使用系统默认ZoneId
     *
     * @param date date
     * @return LocalDateTime
     */
    public static LocalDateTime toLocalDateTime(Date date) {
        return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
    }

    /**
     * date 转 LocalDateTime，指定ZoneId
     *
     * @param date   date
     * @param zoneId ZoneId
     * @return LocalDateTime
     */
    public static LocalDateTime toLocalDateTime(Date date, ZoneId zoneId) {
        return date.toInstant().atZone(zoneId).toLocalDateTime();
    }

    /**
     * LocalDateTime 转 date，使用系统默认ZoneId
     *
     * @param localDateTime localDateTime
     * @return Date
     */
    public static Date toDate(LocalDateTime localDateTime) {
        return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
    }


    /**
     * LocalDateTime 转 date，指定ZoneId
     *
     * @param zoneId        ZoneId
     * @param localDateTime localDateTime
     * @return Date
     */
    public static Date toDate(LocalDateTime localDateTime, ZoneId zoneId) {
        return Date.from(localDateTime.atZone(zoneId).toInstant());
    }

    /**
     * 偏移秒数
     *
     * @param date   日期
     * @param offset 偏移秒数，正数向未来偏移，负数向历史偏移
     * @return 偏移后的日期
     */
    public static Date offsetSecond(final Date date, final int offset) {
        return org.dromara.hutool.core.date.DateUtil.offsetSecond(date, offset);
    }
}
